package com.kzd.gtgame.app

import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.SPStaticUtils
import com.blankj.utilcode.util.SPUtils
import com.kzd.gtgame.entity.UserInfo
import com.kzd.gtgame.entity.UserMine
import kotlin.reflect.KProperty

object SPSConstance {

    private const val SP_NAME_GT_USER = "GT_USER"
    private const val SP_NAME_GT_DEFAULT = "GT_DEFAULT"

    var uid by APreference(
        name = "uid",
        String::class.java,
        SPUtils.getInstance(SP_NAME_GT_USER)
    )

    var userInfo by APreference(
        name = "userInfo",
        UserInfo::class.java,
        SPUtils.getInstance(SP_NAME_GT_USER)
    )

    var userMine by APreference(
        name = "userMine",
        UserMine::class.java,
        SPUtils.getInstance(SP_NAME_GT_USER)
    )

    var memberId by APreference(
        name = "memberId",
        String::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

    var deviceId by APreference(
        name = "deviceId",
        String::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

    var channel by APreference(
        name = "channel",
        String::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

    var forceLogin by APreference(
        name = "forceLogin",
        Boolean::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

    var isFirstInstall by APreference(
        name = "isFirstInstall",
        Boolean::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

    var isReadAgree by APreference(
        name = "isReadAgree",
        Boolean::class.java,
        SPUtils.getInstance(SP_NAME_GT_DEFAULT)
    )

//    fun clearAll() {
//        val memberId = this.memberId
//        SPStaticUtils.clear()
//        this.memberId = memberId
//    }

    fun clearUser(){
        SPUtils.getInstance(SP_NAME_GT_USER).clear()
    }

    fun clearDefault(){
        SPUtils.getInstance(SP_NAME_GT_DEFAULT).clear()
    }

    fun clear(){
//        SPUtils.getInstance().clear()
        SPUtils.getInstance(SP_NAME_GT_USER).clear()
        SPUtils.getInstance(SP_NAME_GT_DEFAULT).clear()
    }
}

@Suppress("UNCHECKED_CAST")
class APreference<T>(var name: String, var type: Class<T>, var spUtils: SPUtils) {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T? =
        getAPreference(name, type, spUtils)

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) =
        putAPreference(name, value, spUtils)

    private fun putAPreference(name: String, value: T?, spUtils: SPUtils) {


        when (value) {
            is Int -> SPStaticUtils.put(name, value, spUtils)
            is Float -> SPStaticUtils.put(name, value, spUtils)
            is Long -> SPStaticUtils.put(name, value, spUtils)
            is Boolean -> SPStaticUtils.put(name, value, spUtils)
            is String -> SPStaticUtils.put(name, value, spUtils)
            else -> {
                SPStaticUtils.put(name, GsonUtils.toJson(value), spUtils)
            }
        }
    }

    private fun getAPreference(name: String, type: Class<T>, spUtils: SPUtils): T? = when {
        type.isAssignableFrom(Int::class.java) -> {
            SPStaticUtils.getInt(name, -1, spUtils) as T
        }
        type.isAssignableFrom(Float::class.java) -> {
            SPStaticUtils.getFloat(name, -1F, spUtils) as T
        }
        type.isAssignableFrom(Long::class.java) -> {
            SPStaticUtils.getLong(name, -1L, spUtils) as T
        }
        type.isAssignableFrom(Boolean::class.java) -> {
            SPStaticUtils.getBoolean(name, false, spUtils) as T
        }
        type.isAssignableFrom(String::class.java) -> {
            SPStaticUtils.getString(name, null, spUtils) as? T
        }
        else -> {
            val value = SPStaticUtils.getString(name, null, spUtils)
            if (value != null)
                GsonUtils.fromJson(value, type)
            else null
        }
    }
}